#include "bsp_button.h"
#include "bsp_beep.h"
#if BUTTON_TM6108
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "esp_log.h"
#include "esp_attr.h"
#include "bsp_param.h"

static const char *TAG = "Touch";
static dedic_gpio_bundle_handle_t bundleA = NULL;
static QueueHandle_t gpio_evt_queue = NULL;
uint32_t btn = 0xff;

static void IRAM_ATTR gpio_isr_handler(void* arg)
{
	btn = dedic_gpio_bundle_read_in(bundleA);
	btn = ((~btn)&0x07) + 1;
	xQueueSendFromISR(gpio_evt_queue, &btn, 0);
}

void button_task(void* arg)
{
	uint32_t button_value = 0xff;
    sys_main_param_t* button_task_param = Get_sys_param_pos();
	for(;;){
		xQueueReceive(gpio_evt_queue, &button_value, portMAX_DELAY);
		ESP_LOGI(TAG,"button_value=%d\n", (int)button_value);
		beep_output(BEEP_BUTTON);
		switch(button_value){
			case KEY_VOICE_MUTE:
				ESP_LOGI(TAG,"声音按键\n");
                if((++button_task_param->sys_vol_switch >= MUSIC_VOLUME_MAX)){
                    button_task_param->sys_vol_switch = MUSIC_CLOSE;
                }
				break;
			case KEY_CHOICE:
				ESP_LOGI(TAG,"选择按键\n");
                // if(button_task_param->sys_status != SYS_RUN_NORMAL){
                if(++button_task_param->sys_pointer_index >= MODE_MAX){
                    button_task_param->sys_pointer_index = MODE_TIME;
                }
                // }
				break;
			case KEY_ADJUST_INCREASE:
				ESP_LOGI(TAG,"增加按键\n");

                switch(button_task_param->sys_pointer_index){
                    case MODE_TIME:
                        if(button_task_param->sys_status != SYS_RUN_NORMAL){
                            if(button_task_param->sys_status == SYS_PAUSE){
                                button_task_param->sys_status = SYS_STOP;
                            }else{
                                if(button_task_param->sys_mode_type_buffer[MODE_TIME] >= 95*60){
                                    button_task_param->sys_mode_type_buffer[MODE_TIME] = 99*60;
                                }else{
                                    if((button_task_param->sys_mode_type_buffer[MODE_TIME] % (5*60)) != 0){
                                        button_task_param->sys_mode_type_buffer[MODE_TIME] += (5*60) - (button_task_param->sys_mode_type_buffer[MODE_TIME] % (5*60));
                                    }else{
                                        button_task_param->sys_mode_type_buffer[MODE_TIME] += (5*60);
                                    }
                                }
                            }
                        }

                        break;
                    case MODE_DLMS:
                        if(button_task_param->sys_status != SYS_RUN_NORMAL){
                            if(button_task_param->sys_mode_type_buffer[MODE_DLMS] != MODE_DLMS_4){

                                button_task_param->sys_mode_type_buffer[MODE_DLMS] += 1;
                            }
                        }

                        break;
                    case MODE_DLQD:
                        if(button_task_param->sys_status == SYS_RUN_NORMAL){
                            if(button_task_param->sys_mode_type_buffer[MODE_DLQD] != POWER_9){

                                button_task_param->sys_mode_type_buffer[MODE_DLQD] += 1;
                            }
                        }

                        break;
                    case MODE_DLPL:
                        if(button_task_param->sys_status == SYS_RUN_NORMAL){
                            if(button_task_param->sys_mode_type_buffer[MODE_DLPL] != POWER_9){
                                button_task_param->sys_mode_type_buffer[MODE_DLPL] += 1;
                            }
                        }

                        break;
                    case MODE_CCQD:

                        if(button_task_param->sys_mode_type_buffer[MODE_CCQD] != POWER_3){

                            button_task_param->sys_mode_type_buffer[MODE_CCQD] += 1;
                        }
                        

                        break;
                    case MODE_CZFD:
                        
                        if(button_task_param->sys_mode_type_buffer[MODE_CZFD] != POWER_3){

                            button_task_param->sys_mode_type_buffer[MODE_CZFD] += 1;
                        }
                        

                        break;
                    case MODE_CZPL:
           
                        if(button_task_param->sys_mode_type_buffer[MODE_CZPL] != POWER_3){

                            button_task_param->sys_mode_type_buffer[MODE_CZPL] += 1;
                        }
                        

                        break;

                    default:
                        break;
                }
                
				break;
			case KEY_ADJUST_DECREASE:
				ESP_LOGI(TAG,"减少按键\n");
                switch(button_task_param->sys_pointer_index){
                    case MODE_TIME:
                        if(button_task_param->sys_status != SYS_RUN_NORMAL){
                            if(button_task_param->sys_status == SYS_PAUSE){
                                button_task_param->sys_status = SYS_STOP;
                            }else{
                                if(button_task_param->sys_mode_type_buffer[MODE_TIME] <= (5*60)){
                                    button_task_param->sys_mode_type_buffer[MODE_TIME] = 1*60;
                                }else{
                                    if((button_task_param->sys_mode_type_buffer[MODE_TIME] % (5*60)) != 0){
                                        button_task_param->sys_mode_type_buffer[MODE_TIME] -= button_task_param->sys_mode_type_buffer[MODE_TIME] % (5*60);
                                    }else{
                                        button_task_param->sys_mode_type_buffer[MODE_TIME] -= (5*60);
                                    }
                                }
                            }
                        }

                        break;
                    case MODE_DLMS:
                        if(button_task_param->sys_status != SYS_RUN_NORMAL){
                            if(button_task_param->sys_mode_type_buffer[MODE_DLMS] != MODE_DLMS_1){

                                button_task_param->sys_mode_type_buffer[MODE_DLMS] -= 1;
                            }
                        }

                        break;
                    case MODE_DLQD:
                        if(button_task_param->sys_status == SYS_RUN_NORMAL){
                            if(button_task_param->sys_mode_type_buffer[MODE_DLQD] != POWER_0){

                                button_task_param->sys_mode_type_buffer[MODE_DLQD] -= 1;
                            }

                        }

                        break;
                    case MODE_DLPL:
                        if(button_task_param->sys_status == SYS_RUN_NORMAL){
                            if(button_task_param->sys_mode_type_buffer[MODE_DLPL] != POWER_1){

                                button_task_param->sys_mode_type_buffer[MODE_DLPL] -= 1;
                            }
                        }

                        break;
                    case MODE_CCQD:
           
                        if(button_task_param->sys_mode_type_buffer[MODE_CCQD] != POWER_0){

                            button_task_param->sys_mode_type_buffer[MODE_CCQD] -= 1;
                        }
                        

                        break;
                    case MODE_CZFD:

                        if(button_task_param->sys_mode_type_buffer[MODE_CZFD] != POWER_0){

                            button_task_param->sys_mode_type_buffer[MODE_CZFD] -= 1;
                        }
                        

                        break;
                    case MODE_CZPL:
                   
                        if(button_task_param->sys_mode_type_buffer[MODE_CZPL] != POWER_0){

                            button_task_param->sys_mode_type_buffer[MODE_CZPL] -= 1;
                        }
                        

                        break;

                    default:
                        break;
                }
                
				break;
			case KEY_START_STOP:
				ESP_LOGI(TAG,"启停按键\n");
                if(button_task_param->sys_status == SYS_RUN_NORMAL){
                    button_task_param->sys_status = SYS_PAUSE;
                }else{
                    button_task_param->sys_status = SYS_RUN_NORMAL;
                }
				break;
			default:
				break;
		}
	}
}

void button_initial()
{
    /* gpio中断 */
	gpio_config_t button_bin3_config = {
		.intr_type = GPIO_INTR_NEGEDGE,
		.pin_bit_mask = 1ULL<<TM6108_GPIO_BIN3,
		.mode = GPIO_MODE_INPUT,
		.pull_up_en = GPIO_PULLUP_ENABLE,
		.pull_down_en = GPIO_PULLDOWN_DISABLE,
	};
	gpio_config(&button_bin3_config);//配置完默认是开启中断

	const int bundleA_gpios[] = {TM6108_GPIO_BIN0, TM6108_GPIO_BIN1, TM6108_GPIO_BIN2};

    dedic_gpio_bundle_config_t bundleA_config = {
        .gpio_array = bundleA_gpios,
        .array_size = ARRAY_SIZE(bundleA_gpios),
        .flags = {
            .in_en = 1,
        },
    };
    dedic_gpio_new_bundle(&bundleA_config, &bundleA);

    gpio_evt_queue = xQueueCreate(10, sizeof(uint32_t));//创建消息队列
	gpio_install_isr_service(ESP_INTR_FLAG_EDGE);//设置中断优先级最低
	gpio_isr_handler_add(TM6108_GPIO_BIN3, gpio_isr_handler, NULL);//注册中断处理程序
	gpio_set_intr_type(TM6108_GPIO_BIN3, GPIO_INTR_NEGEDGE);
	xTaskCreate(&button_task, "button_task", 8192, NULL, 9, NULL);

}
#endif

#if BUTTON_ESP32
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "touch_element/touch_button.h"
#include "esp_log.h"
static const char *TAG = "Touch Button Example";
#define TOUCH_BUTTON_NUM     5
/* Touch buttons handle */
static touch_button_handle_t button_handle[TOUCH_BUTTON_NUM];

/* Touch buttons channel array */
static const touch_pad_t channel_array[TOUCH_BUTTON_NUM] = {
    TOUCH_PAD_NUM1,
    TOUCH_PAD_NUM2,
    TOUCH_PAD_NUM3,
    TOUCH_PAD_NUM4,
    TOUCH_PAD_NUM5,
};

/* Touch buttons channel sensitivity array */
static const float channel_sens_array[TOUCH_BUTTON_NUM] = {
    0.1F,
    0.1F,
    0.1F,
    0.1F,
    0.1F,
};



/* Button event handler task */
static void button_handler_task(void *arg)
{
    (void) arg; //Unused
    touch_elem_message_t element_message;
    while (1) {
        /* Waiting for touch element messages */
        touch_element_message_receive(&element_message, portMAX_DELAY);
        if (element_message.element_type != TOUCH_ELEM_TYPE_BUTTON) {
            continue;
        }
        /* Decode message */
        const touch_button_message_t *button_message = touch_button_get_message(&element_message);
        if (button_message->event == TOUCH_BUTTON_EVT_ON_PRESS) {
            ESP_LOGI(TAG, "Button[%d] Press", (int)element_message.arg);
            beep_output();
        } else if (button_message->event == TOUCH_BUTTON_EVT_ON_RELEASE) {
            ESP_LOGI(TAG, "Button[%d] Release", (int)element_message.arg);
        } else if (button_message->event == TOUCH_BUTTON_EVT_ON_LONGPRESS) {
            ESP_LOGI(TAG, "Button[%d] LongPress", (int)element_message.arg);
        }
    }
}


void button_initial() 
{
    /* Initialize Touch Element library */
    touch_elem_global_config_t global_config = TOUCH_ELEM_GLOBAL_DEFAULT_CONFIG();
    ESP_ERROR_CHECK(touch_element_install(&global_config));
    ESP_LOGI(TAG, "Touch element library installed");

    touch_button_global_config_t button_global_config = TOUCH_BUTTON_GLOBAL_DEFAULT_CONFIG();
    ESP_ERROR_CHECK(touch_button_install(&button_global_config));
    ESP_LOGI(TAG, "Touch button installed");
    for (int i = 0; i < TOUCH_BUTTON_NUM; i++) {
        touch_button_config_t button_config = {
            .channel_num = channel_array[i],
            .channel_sens = channel_sens_array[i]
        };
        /* Create Touch buttons */
        ESP_ERROR_CHECK(touch_button_create(&button_config, &button_handle[i]));
        /* Subscribe touch button events (On Press, On Release, On LongPress) */
        ESP_ERROR_CHECK(touch_button_subscribe_event(button_handle[i],
                        TOUCH_ELEM_EVENT_ON_PRESS | TOUCH_ELEM_EVENT_ON_RELEASE,
                        (void *)channel_array[i]));

        ESP_ERROR_CHECK(touch_button_set_dispatch_method(button_handle[i], TOUCH_ELEM_DISP_EVENT));



	}
    xTaskCreate(&button_handler_task, "button_handler_task", 4 * 1024, NULL, 5, NULL);
	touch_element_start();
    ESP_LOGI(TAG, "Touch element library start");

}






#endif


